home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 2: CDPD 1
/
Almathera Ten on Ten - Disc 2: CDPD 1.iso
/
pd
/
151-175
/
169
/
src
/
shell
/
comm1.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-13
|
12KB
|
648 lines
/*
* COMM1.C
*
* (c)1986 Matthew Dillon 9 October 1986
*
* SLEEP
* NUMBER -handles values as commands, actually a NULL command.
* CAT
* COMMENT
* DIR -also handles DEVINFO
* QUIT -also handles EXIT
* ECHO
* SOURCE
* CD
* MKDIR
* MV
* RM
* HISTORY
* MEM
* FOREACH
* FOREVER
*
* NOTE: SET/UNSET/ALIAS/UNALIAS handled in SET.C
*
*/
#include "shell.h"
#include <stdio.h>
extern LOCK *CreateDir(), *CurrentDir(), *ParentDir();
extern LOCK *Lock(), *DupLock();
extern long disp_entry();
struct FileLock *Clock;
do_sleep()
{
register int i;
if (ac == 2) {
i = atoi(av[1]);
while (i > 0) {
Delay (50*2);
i -= 2;
if (CHECKBREAK())
break;
}
}
return (0);
}
do_number()
{
return (0);
}
do_cat()
{
FILE *fi;
short i;
char buf[256];
if (ac == 1) {
while (fgets(buf, 256, stdin)) {
Write(Cout, buf, strlen(buf));
if (CHECKBREAK())
break;
}
clearerr(stdin);
}
for (i = 1; i < ac; ++i) {
if (fi = fopen (av[i], "r")) {
while (fgets (buf, 256, fi)) {
Write(Cout, buf, strlen(buf));
if (CHECKBREAK())
break;
}
fclose(fi);
} else {
fhprintf (Cerr, "could not open %s\n", av[i]);
}
}
return (0);
}
/*
* comment file string
*/
do_comment(str)
char *str;
{
register char *ptr = next_word(next_word(str));
if (SetComment(av[1], ptr) == 0) {
perror(av[1]);
return(1);
}
return(0);
}
do_dir(garbage, com)
char *garbage;
{
register struct DPTR *dp;
register struct InfoData *info;
char *name;
char br = 0;
register short i;
int stat;
short longmode = 1;
short dcomment = 1;
short avstart = 1;
register long total = 0;
if (av[1][0] == '-') {
++avstart;
for (i = 1; av[1][i]; ++i) {
switch(av[1][i]) {
case 's':
longmode = 0;
break;
case 'l':
longmode = 1;
break;
case 'C':
dcomment = 0;
break;
}
}
}
if (ac == avstart)
av[ac++] = "";
for (i = avstart; !br && i < ac; ++i) {
if ((dp = dopen (av[i], &stat)) == NULL)
continue;
if (com < 0) {
info = (struct InfoData *)AllocMem(sizeof(struct InfoData), MEMF_PUBLIC);
if (Info (dp->lock, info)) {
int bpb = info->id_BytesPerBlock;
fhprintf (Cout, "Unit:%2ld Errs:%3ld Bytes: %-7ld Free: %-7ld %%full: %ld\n",
info->id_UnitNumber,
info->id_NumSoftErrors,
bpb * info->id_NumBlocks,
bpb * (info->id_NumBlocks - info->id_NumBlocksUsed),
info->id_NumBlocksUsed * 100 / info->id_NumBlocks
);
} else {
perror (av[i]);
}
FreeMem (info, sizeof(*info));
} else {
if (stat) {
while (dnext (dp, &name, &stat)) {
total += disp_entry (dp->fib, longmode, dcomment);
if (CHECKBREAK()) {
br = 1;
break;
}
}
} else {
total += disp_entry(dp->fib, longmode, dcomment);
}
}
dclose (dp);
}
fhprintf (Cout, "TOTAL: %ld\n", total);
return (0);
}
static long
disp_entry(fib, lengthy, comment)
register struct FileInfoBlock *fib;
{
char str[6];
char dstr[32];
register char *dirstr;
str[5] = '\0';
str[0] = (fib->fib_Protection & FIBF_READ) ? '-' : 'r';
str[1] = (fib->fib_Protection & FIBF_WRITE) ? '-' : 'w';
str[2] = (fib->fib_Protection & FIBF_EXECUTE) ? '-' : 'x';
str[3] = (fib->fib_Protection & FIBF_DELETE) ? '-' : 'd';
str[4] = (fib->fib_Protection & FIBF_ARCHIVE) ? '-' : 'a';
dirstr = (fib->fib_DirEntryType < 0) ? " " : "DIR";
fhprintf (Cout, "%s %6ld %s %-20s", str, (long)fib->fib_Size,
dirstr, fib->fib_FileName
);
if (lengthy)
fhprintf (Cout, " %s", datetos(&fib->fib_Date, dstr, "D M Y h:m"));
if (comment)
fhprintf (Cout, " %s", fib->fib_Comment);
fhprintf(Cout, "\n");
return ((long)fib->fib_Size);
}
do_quit()
{
if (Src_stack) {
Quit = 1;
return(do_return());
}
main_exit (0);
}
do_echo(str)
char *str;
{
register char *ptr;
char nl = 1;
for (ptr = str; *ptr && *ptr != ' '; ++ptr);
if (*ptr == ' ')
++ptr;
if (av[1] && strcmp (av[1], "-n") == 0) {
nl = 0;
ptr += 2;
if (*ptr == ' ')
++ptr;
}
Write(Cout, ptr, strlen(ptr));
if (nl)
Oputs("");
return (0);
}
do_source(str)
char *str;
{
register FILE *fi;
register char *buf;
buf = malloc(256);
if (buf == NULL) {
Eputs ("no memory");
goto error;
}
if (Src_stack == MAXSRC) {
Eputs ("Too many source levels");
error:
if ((long)av[0] == -1)
UnLock(av[1]);
return(-1);
}
if ((long)av[0] == -1) {
long oldir = (long)CurrentDir(av[1]);
fi = fopen("", "r");
UnLock(CurrentDir(oldir));
} else {
fi = fopen (av[1], "r");
}
if (fi == NULL) {
fhprintf(Cerr, "Cannot open %s\n", next_word(str));
return(-1);
}
set_var(LEVEL_SET, V_PASSED, next_word(next_word(str)));
++H_stack;
Src_pos[Src_stack] = 0;
Src_base[Src_stack] = (long)fi;
++Src_stack;
while (fgets(buf, 256, fi)) {
register int len = strlen(buf);
buf[len-1] = 0; /* remove \n */
Src_pos[Src_stack - 1] += len; /* + (1 + actual length) */
if (Verbose)
Eputs(buf);
exec_command (buf);
if (CHECKBREAK())
break;
}
--H_stack;
--Src_stack;
unset_level(LEVEL_LABEL + Src_stack);
unset_var(LEVEL_SET, V_PASSED);
fclose (fi);
return (0);
}
/*
* CD
*
* CD(str, -1) -do pwd and display current cd. if str = NULL don't disp.
* CD(str, 0) -do CD operation.
*
* standard operation: breakup path by '/'s and process independantly
* x: -reset cwd base
* .. -remove last cwd element
* N -add N or /N to cwd
*/
do_cd(str, com)
register char *str;
{
static char cwd[256];
register char sc, *ptr;
char *name;
if (com < 0) {
register struct FileLock *lock, *newlock;
register FIB *fib;
short i, len;
fib = (FIB *)AllocMem(sizeof(FIB), 0);
Clock = (struct FileLock *)((PROC *)FindTask(0))->pr_CurrentDir;
if (!Clock)
CurrentDir(Clock = Lock(":", ACCESS_READ));
lock = DupLock(Clock);
cwd[i = 255] = '\0';
while (lock) {
newlock = ParentDir(lock);
Examine(lock, fib);
name = fib->fib_FileName;
if (*name == '\0') /* HACK TO FIX RAM: DISK BUG */
name = "ram";
len = strlen(name);
if (newlock) {
if (i == 255) {
i -= len;
bmov(name, cwd + i, len);
} else {
i -= len + 1;
bmov(name, cwd + i, len);
cwd[i+len] = '/';
}
} else {
i -= len + 1;
bmov(name, cwd + i, len);
cwd[i+len] = ':';
}
UnLock(lock);
lock = newlock;
}
FreeMem(fib, sizeof(FIB));
bmov(cwd + i, cwd, 256 - i);
if (str)
Oputs(cwd);
goto cdset;
}
str = next_word(str);
if (*str == '\0')
Oputs(cwd);
str[strlen(str)+1] = '\0'; /* add second \0 on end */
while (*str) {
for (ptr = str; *ptr && *ptr != '/' && *ptr != ':'; ++ptr);
switch (*ptr) {
case ':':
sc = ptr[1];
ptr[1] = '\0';
if (attempt_cd(str))
strcpy(cwd, str);
ptr[1] = sc;
break;
case '\0':
case '/':
*ptr = '\0';
if (strcmp(str, "..") == 0 || str == ptr)
str = "/";
if (*str && attempt_cd(str)) {
if (*str == '/') {
rmlast(cwd);
} else {
if (cwd[0] == 0 || cwd[strlen(cwd)-1] != ':')
strcat(cwd, "/");
strcat(cwd, str);
}
}
break;
}
str = ptr + 1;
}
cdset:
set_var(LEVEL_SET, V_CWD, cwd);
return (0);
}
attempt_cd(str)
char *str;
{
register struct FileLock *oldlock, *filelock;
if (filelock = Lock(str, ACCESS_READ)) {
if (isdir(str)) {
UnLock(CurrentDir(filelock));
Clock = filelock;
return(1);
}
UnLock(filelock);
ierror(str, 212);
} else {
ierror(str, 205);
}
return (0);
}
/*
* remove last component. Start at end and work backwards until reach
* a '/'
*/
rmlast(str)
char *str;
{
register char *ptr = str + strlen(str) - 1;
while (ptr != str && *ptr != '/' && *ptr != ':')
--ptr;
if (*ptr != ':')
ptr[0] = '\0';
else
ptr[1] = '\0';
}
do_mkdir()
{
register short i;
register struct FileLock *lock;
for (i = 1; i < ac; ++i) {
if (lock = CreateDir (av[i])) {
UnLock (lock);
continue;
}
perror (av[i]);
}
return (0);
}
/*
* MV file1 file2
* MV file1 file2....fileN dir
*/
do_mv()
{
char dest[256];
register short i, len;
register char *str;
--ac;
if (isdir(av[ac])) {
len = strlen(av[ac]);
for (i = 1; i < ac; ++i) {
str = av[i] + strlen(av[i]) - 1;
while (str >= av[i] && *str != '/' && *str != ':')
--str;
++str;
if (*str == 0) {
ierror(av[i], 508);
return (-1);
}
strcpy(dest, av[ac]);
if (dest[0] && dest[len-1] != ':' && dest[len-1] != '/')
strcat(dest, "/");
strcat(dest, str);
if (Rename(av[i], dest) == 0)
break;
}
if (i == ac)
return (1);
} else {
i = 1;
if (ac != 2) {
ierror("mv:", 507);
return (-1);
}
if (Rename (av[1], av[2]))
return (0);
}
perror (av[i]);
return (-1);
}
do_rm()
{
register short i, recur;
recur = (strncmp(av[1], "-r", 2)) ? 0 : 1;
for (i = 1 + recur; i < ac; ++i) {
if (isdir(av[i]) && recur)
rmdir(av[i]);
if (!DeleteFile(av[i]))
perror(av[i]);
}
return (0);
}
rmdir(name)
char *name;
{
register LOCK *lock, *cwd;
register FIB *fib;
register char *buf;
buf = (char *)AllocMem(256, 0);
fib = (FIB *)AllocMem(sizeof(FIB), 0);
if (lock = Lock(name, ACCESS_READ)) {
cwd = CurrentDir(lock);
if (Examine(lock, fib)) {
buf[0] = 0;
while (ExNext(lock, fib)) {
if (isdir(fib->fib_FileName))
rmdir(fib->fib_FileName);
if (buf[0]) {
if (!DeleteFile(buf))
perror(buf);
}
strcpy(buf, fib->fib_FileName);
}
if (buf[0]) {
if (!DeleteFile(buf))
perror(buf);
}
}
UnLock(CurrentDir(cwd));
} else {
perror(name);
}
FreeMem(fib, sizeof(FIB));
FreeMem(buf, 256);
}
do_history()
{
register struct HIST *hist;
register short i = H_tail_base;
register short len = (av[1]) ? strlen(av[1]) : 0;
for (hist = H_tail; hist; hist = hist->prev) {
if (len == 0 || strncmp(av[1], hist->line, len) == 0) {
fhprintf (Cout, "%3ld ", i);
Oputs (hist->line);
}
++i;
if (CHECKBREAK())
break;
}
return (0);
}
do_mem()
{
register long cfree, ffree;
extern long AvailMem();
Forbid();
cfree = AvailMem (MEMF_CHIP);
ffree = AvailMem (MEMF_FAST);
Permit();
if (ffree)
fhprintf (Cout, "FAST memory:%10ld\n", ffree);
fhprintf (Cout, "CHIP memory:%10ld\n", cfree);
fhprintf (Cout, "Total -----:%5ld K\n", (ffree + cfree) >> 10);
return (0);
}
/*
* foreach var_name ( str str str str... str ) commands
* spacing is important (unfortunetly)
*
* ac=0 1 2 3 4 5 6 7
* foreach i ( a b c ) echo $i
* foreach i ( *.c ) "echo -n "file ->";echo $i"
*/
do_foreach()
{
register short i, cstart, cend, old;
register char *cstr, *vname, *ptr, *scr, *args;
cstart = i = (*av[2] == '(') ? 3 : 2;
while (i < ac) {
if (*av[i] == ')')
break;
++i;
}
if (i == ac) {
Eputs ("')' expected");
return (-1);
}
++H_stack;
cend = i;
vname = strcpy(malloc(strlen(av[1])+1), av[1]);
cstr = compile_av (av, cend + 1, ac);
ptr = args = compile_av (av, cstart, cend);
while (*ptr) {
while (*ptr == ' ' || *ptr == 9)
++ptr;
scr = ptr;
if (*scr == '\0')
break;
while (*ptr && *ptr != ' ' && *ptr != 9)
++ptr;
old = *ptr;
*ptr = '\0';
set_var (LEVEL_SET, vname, scr);
if (CHECKBREAK())
break;
exec_command (cstr);
*ptr = old;
}
--H_stack;
free (args);
free (cstr);
unset_var (LEVEL_SET, vname);
free (vname);
return (0);
}
do_forever(str)
register char *str;
{
long rcode = 0;
register char *ptr = next_word(str);
++H_stack;
for (;;) {
if (CHECKBREAK()) {
rcode = 20;
break;
}
if (exec_command (ptr) < 0) {
str = get_var(LEVEL_SET, V_LASTERR);
rcode = (str) ? atoi(str) : 20;
break;
}
}
--H_stack;
return (rcode);
}